package com.starbaba.weixin.view;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import com.jumai.server.common.util.ApplicationProperties;
import com.tuanzi.server.loan_base.model.request.wechat.UploadPermanentImageRequest;
import com.tuanzi.server.loan_base.model.response.commom.Result;
import com.tuanzi.server.loan_base.model.response.commom.ResultUtils;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.json.annotations.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.FileCopyUtils;

import com.base.common.database.BaseDao;
import com.base.common.exception.AppException;
import com.base.common.log.LogService;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.jumai.server.qiniu.QiniuUploadUtils;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.qiniu.common.Zone;
import com.qiniu.storage.Configuration;
import com.starbaba.controllog.aop.IActionLogAble;
import com.starbaba.controllog.model.ControlLogCategory;
import com.starbaba.core.utils.Struts2Utils;
import com.starbaba.core.web.constant.WebConstants;
import com.starbaba.model.dictionary.Constant;
import com.starbaba.model.network.Phead;
import com.starbaba.model.utils.HttpConnectionUtils;
import com.starbaba.redis.JedisUtils;
import com.starbaba.system.user.model.UserVO;
import com.starbaba.util.QueryListUtil;
import com.starbaba.utils.WeixinUtils;
import com.starbaba.weixin.model.QueryListVO;
import com.starbaba.weixin.model.WeixinMenuDbVO;
import com.starbaba.weixin.model.WeixinMenuVO;
import com.starbaba.weixin.model.WeixinMessage;
import com.starbaba.weixin.service.WeixinActivityService;
import com.starbaba.weixin.service.WeixinMenuService;
import com.starbaba.weixin.service.impl.WeixinActivityServiceImpl;
import com.tuanzi.server.loan_base.constant.WeixinRedisKey;

/**
 * @author Yukinomiu
 * @version 1.0
 */
public class WeixinActivityAction extends ActionSupport implements IActionLogAble, ModelDriven {

    private static final long serialVersionUID = -7999365233105743577L;
    private static final String LOGGER_NAME = WeixinActivityAction.class.getName();

    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    private static final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<>();

    // 页面数据模型
    private Set<String> allChannels;
    
    private Set<String> codeChannels;

	private List<String> keywordList;

    private Map<String, Object> params = new HashMap<>();

    private String savePath;

    //回复类型图文对应的图片文件
    private File upload;
    
    private String uploadFileName;
    
    //回复类型图片对应的图片文件
    private File imageFile;
    
   //回复类型图片对应的图片名
    private String imageFileFileName;

    private String uploadContentType;
    

//    @SuppressWarnings("SpringJavaAutowiredMembersInspection")
//    @Autowired
//    @Qualifier("WeixinActivityServiceImpl")
    private WeixinActivityService service;

    @SuppressWarnings("SpringJavaAutowiredMembersInspection")
    @Autowired
    @Qualifier("WeixinMenuServiceImpl")
    private WeixinMenuService menuService;

    private QueryListUtil.DataTableResponseInfo responseInfo;

    private Map<String, Object> responseMap;

    private Set<String> activityNameList;

    private InputStream inputStream;

    private String fileName;

    public WeixinActivityAction() {
    	service = new WeixinActivityServiceImpl();
    }

    public String showPage() {
        allChannels = service.getAllChannels();
        return SUCCESS;
    }

    public String showPageSum() {
    	allChannels = service.getAllChannels();
        codeChannels = service.getCodeChannels();
        return SUCCESS;
    }

    public String showCustomerPageSum() {
        return SUCCESS;
    }

    public String showRedpackPage() {
        activityNameList = service.getAllActivityNames();
        return SUCCESS;
    }

    public String showRedpackStat() {
        activityNameList = service.getAllActivityNames();
        return SUCCESS;
    }

    public String showMenuPage() {
        return SUCCESS;
    }

    public String showKeywordPage() {
        BaseDao baseDao = new BaseDao(Constant.POOL_LIFE);
        keywordList = new LinkedList<>();
        try {
            List<Keyword> list = baseDao.list("select distinct keyword as name from loan.weixin_feedback_info", Keyword.class, new ArrayList<>(0));
            for (Keyword k : list) {
                keywordList.add(k.getName());
            }
        } catch (AppException e) {
            LogService.error(e);
            keywordList = new ArrayList<>(0);
        }
        return SUCCESS;
    }

    public String showKeywordEditPage() {
        HttpServletRequest request = ServletActionContext.getRequest();
        String action = request.getParameter("action");
        if ("edit".equals(action)) {
            String id = request.getParameter("id");
            params.put("id", id);
        }
        return SUCCESS;
    }

    public String getRecord() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Integer echo;
        Calendar c = Calendar.getInstance();
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", getSimpleDateFormat().parse((String) params.get("startDate")));
            }
            if (params.get("endDate") != null) {
                Date endDate = getSimpleDateFormat().parse((String) params.get("endDate"));
                c.setTime(endDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("endDate", c.getTime());
            }
            if (params.get("channel") != null) {
                queryParams.put("channel", params.get("channel"));
            }
            if (params.get("platform") != null) {
                Integer platform = Integer.valueOf((String) params.get("platform"));
                if (platform == 0 || platform == 1 || platform == 2 || platform == -1 || platform == -2) {
                    queryParams.put("platform", platform);
                }
            }
            if (params.get("type") != null) {
                Integer type = Integer.valueOf((String) params.get("type"));
                if (type == 0 || type == 1) {
                    queryParams.put("type", type);
                }
            }
            if (params.get("openId") != null) {
                queryParams.put("openId", params.get("openId"));
            }
            if (params.get("phone") != null) {
                queryParams.put("phone", params.get("phone"));
            }
            if (params.get("status") != null) {
                String status = (String) params.get("status");
                Integer s = Integer.valueOf(status);
                queryParams.put("status", s);
            }
            if (params.get("couponChannel") != null) {
                queryParams.put("couponChannel", params.get("couponChannel"));
            }

            // 表单控件参数
            QueryListUtil.DataTableRequestInfo info = QueryListUtil.getDataTableRequestInfo(params);

            echo = info.getEcho();

            Integer start = info.getStart();
            Integer limit = info.getLimit();

            queryParams.put("start", start);
            queryParams.put("limit", limit);
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            QueryListVO result = service.getRecordList(queryParams);
            responseInfo = QueryListUtil.getDataTableResponseInfo(echo, result.getTotalCount(), result.getList());
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }

    public String getRecordSum() {
        // long startTime = System.currentTimeMillis();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Integer echo;
        Calendar c = Calendar.getInstance();
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", getSimpleDateFormat().parse((String) params.get("startDate")));
            }
            if (params.get("endDate") != null) {
                Date endDate = getSimpleDateFormat().parse((String) params.get("endDate"));
                c.setTime(endDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("endDate", c.getTime());
            }
            if (params.get("platform") != null) {
                Integer platform = Integer.valueOf((String) params.get("platform"));
                if (platform == 0 || platform == 1 || platform == 2) {
                    queryParams.put("platform", platform);
                }
            }
            if (params.get("codeChannel") != null) {
                queryParams.put("codeChannel", params.get("codeChannel"));
            }
            if (params.get("type") != null) {
                Integer type = Integer.valueOf((String) params.get("type"));
                if (type == 0 || type == 1) {
                    queryParams.put("type", type);
                }
            }
            if (params.get("channel") != null) {
            	 queryParams.put("channel", params.get("channel"));
            }

            // 表单控件参数
            QueryListUtil.DataTableRequestInfo info = QueryListUtil.getDataTableRequestInfo(params);

            echo = info.getEcho();

            Integer start = info.getStart();
            Integer limit = info.getLimit();

            queryParams.put("start", start);
            queryParams.put("limit", limit);
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            QueryListVO result = service.getList(queryParams);
            responseInfo = QueryListUtil.getDataTableResponseInfo(echo, result.getTotalCount(), result.getList());
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        // System.out.println(System.currentTimeMillis() - startTime);
        return SUCCESS;
    }

    public String getCustomerRecordSum() {
        // long startTime = System.currentTimeMillis();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Integer echo;
        String userId;
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", getSimpleDateFormat().parse((String) params.get("startDate")));
            }
            if (params.get("endDate") != null) {
                Calendar c = Calendar.getInstance();
                Date endDate = getSimpleDateFormat().parse((String) params.get("endDate"));
                c.setTime(endDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("endDate", c.getTime());
            }
            if (params.get("type") != null) {
                Integer type = Integer.valueOf((String) params.get("type"));
                if (type == 0 || type == 1) {
                    queryParams.put("type", type);
                }
            }

            // 获取用户ID
            Object obj = Struts2Utils.getSessionAttribute(WebConstants.SESSION_ATTRIBUTE_USER);
            if (obj == null) {
                LogService.info(WeixinActivityAction.class.getName(), "无法获取当前登录用户");
                return ERROR;
            }
            userId = ((UserVO) obj).getUserid();
            queryParams.put("userId", userId);

            // 表单控件参数
            QueryListUtil.DataTableRequestInfo info = QueryListUtil.getDataTableRequestInfo(params);

            echo = info.getEcho();

            Integer start = info.getStart();
            Integer limit = info.getLimit();

            queryParams.put("start", start);
            queryParams.put("limit", limit);
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            QueryListVO result = service.getCustomerList(queryParams);
            responseInfo = QueryListUtil.getDataTableResponseInfo(echo, result.getTotalCount(), result.getList());
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        // System.out.println(System.currentTimeMillis() - startTime);
        return SUCCESS;
    }

    public String changeChannel() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Integer startIndex;
        Integer endIndex;
        String channelName;
        try {
            startIndex = Integer.valueOf((String) params.get("start"));
            endIndex = Integer.valueOf((String) params.get("end"));
            channelName = (String) params.get("name");
            channelName = channelName.trim();
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求参数解析异常: " + e.getMessage());
            setResponseJson(2, "请求参数非法");
            return SUCCESS;
        }

        try {
            Map<String, Object> updateParams = new HashMap<>(3, 1);
            updateParams.put("startIndex", startIndex);
            updateParams.put("endIndex", endIndex);
            updateParams.put("channelName", channelName);
            service.changeChannelName(updateParams);
        } catch (Exception e) {
            LogService.error("修改优惠码渠道异常", e);
            setResponseJson(-1, "服务器错误, 请稍后重试");
            return SUCCESS;
        }

        setResponseJson(1, "修改成功!");
        return SUCCESS;
    }

    public String getRedpackRecord() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Integer echo;
        Calendar c = Calendar.getInstance();
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", getSimpleDateFormat().parse((String) params.get("startDate")));
            }
            if (params.get("endDate") != null) {
                Date endDate = getSimpleDateFormat().parse((String) params.get("endDate"));
                c.setTime(endDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("endDate", c.getTime());
            }
            if (params.get("sendStartDate") != null) {
                queryParams.put("sendStartDate", getSimpleDateFormat().parse((String) params.get("sendStartDate")));
            }
            if (params.get("sendEndDate") != null) {
                Date sendEndDate = getSimpleDateFormat().parse((String) params.get("sendEndDate"));
                c.setTime(sendEndDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("sendEndDate", c.getTime());
            }
            if (params.get("phone") != null) {
                queryParams.put("phone", params.get("phone"));
            }
            if (params.get("status") != null) {
                queryParams.put("status", params.get("status"));
            }
            if (params.get("activityName") != null) {
                queryParams.put("activityName", params.get("activityName"));
            }
            if (params.get("product") != null) {
                queryParams.put("product", params.get("product"));
            }
            if (params.get("currentState") != null) {
                queryParams.put("currentState", params.get("currentState"));
            }
            if (params.get("billno") != null) {
                queryParams.put("billno", params.get("billno"));
            }

            // 表单控件参数
            QueryListUtil.DataTableRequestInfo info = QueryListUtil.getDataTableRequestInfo(params);

            echo = info.getEcho();

            Integer start = info.getStart();
            Integer limit = info.getLimit();

            queryParams.put("start", start);
            queryParams.put("limit", limit);
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            QueryListVO result = service.getRedpackList(queryParams);
            responseInfo = QueryListUtil.getDataTableResponseInfo(echo, result.getTotalCount(), result.getList());
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        // System.out.println(System.currentTimeMillis() - startTime);
        return SUCCESS;
    }

    public String getRedpackStatList() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Integer echo;
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", (String) params.get("startDate"));
            }

            if (params.get("endDate") != null) {
                queryParams.put("endDate", (String) params.get("endDate"));
            }

            if (params.get("activityName") != null) {
                queryParams.put("activityName", params.get("activityName"));
            }

            // 表单控件参数
            QueryListUtil.DataTableRequestInfo info = QueryListUtil.getDataTableRequestInfo(params);
            echo = info.getEcho();

            Integer start = info.getStart();
            Integer limit = info.getLimit();

            queryParams.put("start", start);
            queryParams.put("limit", limit);
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            QueryListVO result = service.getRedpackStatList(queryParams);
            responseInfo = QueryListUtil.getDataTableResponseInfo(echo, result.getTotalCount(), result.getList());
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        return SUCCESS;
    }

    public String exportRedpackRecord() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Calendar c = Calendar.getInstance();
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", getSimpleDateFormat().parse((String) params.get("startDate")));
            }
            if (params.get("endDate") != null) {
                Date endDate = getSimpleDateFormat().parse((String) params.get("endDate"));
                c.setTime(endDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("endDate", c.getTime());
            }
            if (params.get("sendStartDate") != null) {
                queryParams.put("sendStartDate", getSimpleDateFormat().parse((String) params.get("sendStartDate")));
            }
            if (params.get("sendEndDate") != null) {
                Date sendEndDate = getSimpleDateFormat().parse((String) params.get("sendEndDate"));
                c.setTime(sendEndDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("sendEndDate", c.getTime());
            }
            if (params.get("phone") != null) {
                queryParams.put("phone", params.get("phone"));
            }
            if (params.get("status") != null) {
                queryParams.put("status", params.get("status"));
            }
            if (params.get("activityName") != null) {
                queryParams.put("activityName", params.get("activityName"));
            }
            if (params.get("product") != null) {
                queryParams.put("product", params.get("product"));
            }
            if (params.get("currentState") != null) {
                queryParams.put("currentState", params.get("currentState"));
            }
            if (params.get("billno") != null) {
                queryParams.put("billno", params.get("billno"));
            }
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            String result = service.exportRedpackList(queryParams);
            inputStream = new ByteArrayInputStream(result.getBytes("GBK"));
            fileName = "Redpack Export-" + System.currentTimeMillis() + ".csv";
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        return SUCCESS;
    }

    public String exportWeinxinRecord() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Calendar c = Calendar.getInstance();
        try {
        	 // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", getSimpleDateFormat().parse((String) params.get("startDate")));
            }
            if (params.get("endDate") != null) {
                Date endDate = getSimpleDateFormat().parse((String) params.get("endDate"));
                c.setTime(endDate);
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.set(Calendar.MILLISECOND, 0);
                queryParams.put("endDate", c.getTime());
            }
            if (params.get("platform") != null) {
                Integer platform = Integer.valueOf((String) params.get("platform"));
                if (platform == 0 || platform == 1 || platform == 2) {
                    queryParams.put("platform", platform);
                }
            }
            if (params.get("codeChannel") != null) {
                queryParams.put("codeChannel", params.get("codeChannel"));
            }
            if (params.get("type") != null) {
                Integer type = Integer.valueOf((String) params.get("type"));
                if (type == 0 || type == 1) {
                    queryParams.put("type", type);
                }
            }
            if (params.get("channel") != null) {
            	 queryParams.put("channel", params.get("channel"));
            }
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            String result = service.exportWeixinList(queryParams);
            inputStream = new ByteArrayInputStream(result.getBytes("GBK"));
            fileName = "Weixin Export-" + System.currentTimeMillis() + ".csv";
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        return SUCCESS;
    }
    
    public String exportRedpackStatList() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        try {
            // 查询参数
            if (params.get("startDate") != null) {
                queryParams.put("startDate", params.get("startDate"));
            }
            if (params.get("endDate") != null) {
                queryParams.put("endDate", params.get("endDate"));
            }
            if (params.get("activityName") != null) {
                queryParams.put("activityName", params.get("activityName"));
            }
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            String result = service.exportStatList(queryParams);
            inputStream = new ByteArrayInputStream(result.getBytes("GBK"));
            fileName = "Redpack-Statistic-Export-" + System.currentTimeMillis() + ".csv";
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }

        return SUCCESS;
    }

    public String submitMenu() {
        responseMap = new HashMap<>();
        HttpServletRequest request = ServletActionContext.getRequest();

        JsonObject configObject;
        Integer weixinType;
        String remark = null;
        WeixinMenuVO vo;
        try {
            String json = QueryListUtil.getBodyString(request);
            if (json == null) {
                throw new NullPointerException("请求参数为空");
            }

            JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
            configObject = jsonObject.getAsJsonObject("config");
            weixinType = jsonObject.get("account").getAsInt();

            JsonElement e = jsonObject.get("remark");
            if (e != null) {
                remark = e.getAsString();
            }

            vo = menuService.convert(configObject);

            if (vo == null) {
                throw new NullPointerException("解析错误");
            }
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 获取Json异常", e);
            responseMap.put("status", -2);
            responseMap.put("msg", "请求参数错误");
            return SUCCESS;
        }

        // 保存到数据库
        try {
            menuService.save(vo, remark, weixinType);
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 保存菜单配置异常", e);
            responseMap.put("status", -1);
            responseMap.put("msg", "服务异常");
            return SUCCESS;
        }

        responseMap.put("status", 0);
        responseMap.put("msg", "请求成功");
        return SUCCESS;
    }

    public String getLastMenu() {
        responseMap = new HashMap<>();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Integer account;
        try {
            account = Integer.valueOf((String) params.get("account"));
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 获取参数异常", e);
            responseMap.put("status", -2);
            responseMap.put("msg", "请求参数错误");
            return SUCCESS;
        }

        String json = null;
        String remark = null;
        try {
            WeixinMenuDbVO dbVO = menuService.getLastMenuConfig(account);
            if (dbVO != null) {
                remark = dbVO.getRoot().getRemark();
                json = menuService.toString(dbVO.getMenuVO());
            }
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 获取配置异常", e);
            responseMap.put("status", -1);
            responseMap.put("msg", "服务异常");
            return SUCCESS;
        }

        responseMap.put("status", 0);
        responseMap.put("msg", "请求成功");
        responseMap.put("data", json);
        responseMap.put("remark", remark);
        return SUCCESS;
    }

    public String applyMenu() {
        responseMap = new HashMap<>();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Integer weixinType;
        try {
            weixinType = Integer.valueOf((String) params.get("weixinType"));
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 获取参数异常", e);
            responseMap.put("status", -2);
            responseMap.put("msg", "请求参数错误");
            return SUCCESS;
        }

        JsonObject json = null;
        try {
            WeixinMenuDbVO dbVO = menuService.getLastMenuConfig(weixinType);
            if (dbVO != null) {
                json = menuService.convert(dbVO.getMenuVO());
            }
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 获取配置异常", e);
            responseMap.put("status", -1);
            responseMap.put("msg", "服务异常");
            return SUCCESS;
        }

        if (json == null) {
            responseMap.put("status", 1);
            responseMap.put("msg", "无已保存的配置, 无法应用");
            return SUCCESS;
        }

        // 调用微信接口
        try {
            JsonObject data = new JsonObject();
            data.add("config", json);
            data.add("weixinType", new JsonPrimitive(weixinType));
            data.add("phead", new Gson().toJsonTree(new Phead()));

            ArrayList<BasicNameValuePair> list = new ArrayList<>();
            list.add(new BasicNameValuePair("data", data.toString()));

            String url = Constant.COMMON_HOST + "/loan_weixin/common?funid=15&rd=" + System.currentTimeMillis();
//             String url = "http://localhost:8090/common?funid=15&rd=" + System.currentTimeMillis();
            String response = HttpConnectionUtils.connection(url, HttpConnectionUtils.POST, list);
            if (response == null) {
                throw new NullPointerException("调用转发接口响应为空");
            }
            LogService.info(LOGGER_NAME + ": 微信转发接口响应: " + response);

            JsonObject rsp = new JsonParser().parse(response).getAsJsonObject();
            int callStatus = rsp.get("callStatus").getAsInt();
            String callMsg = rsp.get("callMsg").getAsString();
            String weixinRsp = rsp.get("weixinRsp") == null ? null : rsp.get("weixinRsp").getAsString();

            if (callStatus != 1) {
                responseMap.put("status", 2);
                responseMap.put("msg", "调用微信转发接口错误, 转发接口返回信息: " + callMsg);
                return SUCCESS;
            }
            else {
                responseMap.put("status", 0);
                responseMap.put("weixinRsp", weixinRsp);
                responseMap.put("msg", "应用成功");
            }
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 调用微信转发接口异常", e);
            responseMap.put("status", -1);
            responseMap.put("msg", "调用微信转发接口错误");
            return SUCCESS;
        }

        return SUCCESS;
    }

    public String addKeyword() {
        responseMap = new HashMap<>();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Integer weixinType;
        try {
            String keyword = (String) params.get("keyword");
            String approximate = (String) params.get("approximate");
            Integer status = Integer.valueOf((String) params.get("status"));
            Integer idx = Integer.valueOf((String) params.get("idx"));
            Integer account = Integer.valueOf((String) params.get("account"));
            String type = (String) params.get("type");
            String isSub = (String) params.get("sub");
            String is_coupon = (String)params.get("is_coupon");

            weixinType = account;

            WeixinMessage message = new WeixinMessage();
            message.setStatus(status);
            message.setOrderNum(idx);
            message.setSource(account);

            if (isSub != null && "true".equals(isSub)) {
                message.setKeyword("<关注回复>");
                message.setSubscribe(1);
                message.setApproximate(0);
            }
            else {
                message.setKeyword(keyword);
                message.setSubscribe(0);

                if (is_coupon != null && "true".equals(is_coupon)) {
                    message.setIs_coupon(1);
                }
                else {
                    message.setIs_coupon(0);
                }
                
                if (approximate != null && "true".equals(approximate)) {
                    message.setApproximate(1);
                }
                else {
                    message.setApproximate(0);
                }
            }

            if ("0".equals(type)) {
                // 文本信息
                String replay = (String) params.get("replay");

                message.setType(0);
                message.setReplay(replay);
            }
            else if ("1".equals(type)) {
                // 图文信息
                String title = (String) params.get("title");
                String desc = (String) params.get("desc");
                String link = (String) params.get("link");

                String picUrl = uploadPictureToQiniu(this.upload);

                message.setType(1);
                message.setTitle(title);
                message.setDesc(desc);
                message.setPicUrl(picUrl);
                message.setUrl(link);
            }
            else if ("2".equals(type)) {
                // 外部链接
                String api = (String) params.get("api");

                message.setType(2);
                message.setApi(api);
            }
            else if ("3".equals(type)){
            	//图片
            	String picUrl = uploadPictureToQiniu(this.imageFile);
            	String mediaId = uploadPermanentImage(account.toString(), picUrl);
            	message.setType(3);
            	message.setPicUrl(picUrl);
            	message.setMediaId(mediaId);
            }
            else {
                throw new IllegalArgumentException("回复类型不支持");
            }

            BaseDao baseDao = new BaseDao(Constant.POOL_LIFE);
            baseDao.add(message);
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 保存微信回复配置异常", e);
            responseMap.put("status", -1);
            responseMap.put("msg", e.getMessage());
            return ERROR;
        }

        updateWeixinKeywordCache(weixinType);

        responseMap.put("status", 1);
        responseMap.put("msg", "添加成功");
        return SUCCESS;
    }

    public String listKeyword() {
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Map<String, Object> queryParams = new HashMap<>();
        Integer echo;

        Integer start;
        Integer limit;
        try {
            // 查询参数
            if (params.get("account") != null) {
                queryParams.put("source", Integer.valueOf((String) params.get("account")));
            }

            if (params.get("status") != null) {
                queryParams.put("status", Integer.valueOf((String) params.get("status")));
            }

            if (params.get("keyword") != null) {
                queryParams.put("keyword", params.get("keyword"));
            }

            if (params.get("type") != null) {
                queryParams.put("type", Integer.valueOf((String) params.get("type")));
            }

            if (params.get("subscribe") != null) {
                queryParams.put("subscribe", Integer.valueOf((String) params.get("subscribe")));
            }

            if (params.get("approximate") != null) {
                queryParams.put("approximate", Integer.valueOf((String) params.get("approximate")));
            }
            
            if (params.get("is_coupon") != null) {
                queryParams.put("is_coupon", Integer.valueOf((String) params.get("is_coupon")));
            }

            // 表单控件参数
            QueryListUtil.DataTableRequestInfo info = QueryListUtil.getDataTableRequestInfo(params);

            echo = info.getEcho();

            start = info.getStart();
            limit = info.getLimit();
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "请求解析异常: " + e.getMessage());
            return ERROR;
        }

        try {
            BaseDao baseDao = new BaseDao(Constant.POOL_LIFE);
            List<Object> sqlParams = new LinkedList<>();
            String fromSql = "from loan.weixin_feedback_info i where 1 = 1";
            for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
                fromSql += " and " + entry.getKey() + " = ?";
                sqlParams.add(entry.getValue());
            }

            Integer count = baseDao.getInt("select count(*) " + fromSql, sqlParams);
            List<WeixinMessage> list;
            if (count > 0) {
                String getSql = "select * " + fromSql + " limit ?, ?";
                sqlParams.add(start);
                sqlParams.add(limit);
                list = baseDao.list(getSql, WeixinMessage.class, sqlParams);
            }
            else {
                list = new ArrayList<>(0);
            }

            QueryListVO result = new QueryListVO(count, list);
            responseInfo = QueryListUtil.getDataTableResponseInfo(echo, result.getTotalCount(), result.getList());
        } catch (Exception e) {
            LogService.info(WeixinActivityAction.class.getName(), "查询数据库异常: " + e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }

    public String updateStatus() {
        responseMap = new HashMap<>();
        HttpServletRequest request = ServletActionContext.getRequest();
        String $action = request.getParameter("action");
        String $id = request.getParameter("id");
        String $newStatus = request.getParameter("newStatus");

        Integer weixinType = null;
        try {
            BaseDao baseDao = new BaseDao(Constant.POOL_LIFE);
            Long id = Long.valueOf($id);
            WeixinMessage message = baseDao.get("select * from loan.weixin_feedback_info i where i.id = ?", WeixinMessage.class, id);
            weixinType = message.getSource();

            if ("update".equals($action)) {
                Integer newStatus = Integer.valueOf($newStatus);

                message.setStatus(newStatus);
                baseDao.update(message, "id");
            }
            else if ("delete".equals($action)) {
                baseDao.delete("delete from loan.weixin_feedback_info where id = ?", id);
            }
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 修改关键字信息异常", e);
            responseMap.put("status", -1);
            return SUCCESS;
        }

        updateWeixinKeywordCache(weixinType);

        responseMap.put("status", 0);
        return SUCCESS;
    }

    public String getKeyword() {
        responseMap = new HashMap<>();
        HttpServletRequest request = ServletActionContext.getRequest();

        String id = request.getParameter("id");
        if (StringUtils.isNotEmpty(id)) {
        	BaseDao baseDao = new BaseDao(Constant.POOL_LIFE);
        	try {
        		WeixinMessage m = baseDao.get("select * from loan.weixin_feedback_info i where i.id = ?", WeixinMessage.class, id);
        		if (m != null) {
        			responseMap.put("data", m);
        		}
        	} catch (Exception e) {
        		LogService.error(LOGGER_NAME + ": 获取微信关键字错误", e);
        		responseMap.put("status", -1);
        		return SUCCESS;
        	}
		}

        responseMap.put("status", 0);
        return SUCCESS;
    }

    public String updateKeyword() {
        responseMap = new HashMap<>();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        Integer weixinType;
        Integer oldWeixinType;
        try {
            Long id = Long.valueOf((String) params.get("id"));
            String keyword = (String) params.get("keyword");
            String approximate = (String) params.get("approximate");
            Integer status = Integer.valueOf((String) params.get("status"));
            Integer idx = Integer.valueOf((String) params.get("idx"));
            Integer account = Integer.valueOf((String) params.get("account"));
            String type = (String) params.get("type");
            String isSub = (String) params.get("sub");
            String is_coupon = (String) params.get("is_coupon");
            weixinType = account;

            WeixinMessage message = new WeixinMessage();
            message.setId(id);
            message.setStatus(status);
            message.setOrderNum(idx);
            message.setSource(account);

            if (isSub != null && "true".equals(isSub)) {
                message.setKeyword("<关注回复>");
                message.setSubscribe(1);
                message.setApproximate(0);
            }
            else {
                message.setKeyword(keyword);
                message.setSubscribe(0);
                
                if (is_coupon != null && "true".equals(is_coupon)) {
                    message.setIs_coupon(1);
                }
                else {
                    message.setIs_coupon(0);
                }
                
                if (approximate != null && "true".equals(approximate)) {
                    message.setApproximate(1);
                }
                else {
                    message.setApproximate(0);
                }
            }

            if ("0".equals(type)) {
                // 文本信息
                String replay = (String) params.get("replay");

                message.setType(0);
                message.setReplay(replay);

                message.setTitle("");
                message.setDesc("");
                message.setPicUrl("");
                message.setUrl("");
                message.setApi("");
            }
            else if ("1".equals(type)) {
                // 图文信息
                String title = (String) params.get("title");
                String desc = (String) params.get("desc");
                String link = (String) params.get("link");

                String url = uploadPictureToQiniu(this.upload);

                message.setType(1);

                message.setTitle(title);
                message.setDesc(desc);
                message.setPicUrl(url);
                message.setUrl(link);

                message.setApi("");
                message.setReplay("");
            }
            else if ("2".equals(type)) {
            	//外部API
                String api = (String) params.get("api");

                message.setType(2);
                message.setApi(api);

                message.setTitle("");
                message.setDesc("");
                message.setPicUrl("");
                message.setUrl("");
                message.setReplay("");
            }
            else if ("3".equals(type)){
            	//图片
            	String picUrl =  uploadPictureToQiniu(this.imageFile);
            	String mediaId = uploadPermanentImage(account.toString(), picUrl);;
            	message.setType(3);
            	message.setPicUrl(picUrl);
            	message.setMediaId(mediaId);
            }
            else {
                throw new IllegalArgumentException("回复类型不支持");
            }

            BaseDao baseDao = new BaseDao(Constant.POOL_LIFE);

            WeixinMessage oldMessage = baseDao.get("select * from loan.weixin_feedback_info i where i.id = ?", WeixinMessage.class, id);
            oldWeixinType = oldMessage.getSource();

            baseDao.update(message, "id");
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": 更新微信回复配置异常", e);
            responseMap.put("status", -1);
            responseMap.put("msg", e.getMessage());
            return ERROR;
        }

        updateWeixinKeywordCache(weixinType);
        updateWeixinKeywordCache(oldWeixinType);

        responseMap.put("status", 1);
        responseMap.put("msg", "更新成功");
        return SUCCESS;
    }

    public String forwardToWeixin() {
        responseMap = new HashMap<>();
        Map<String, Object> params = QueryListUtil.getRequestParamsMap(ServletActionContext.getRequest());
        QueryListUtil.dropEmptyParams(params);

        String uri = (String) params.get("uri");
        String data = (String) params.get("data");

        ArrayList<BasicNameValuePair> list = new ArrayList<>();
        list.add(new BasicNameValuePair("data", data));

        String url = Constant.COMMON_HOST + uri;
        // String url = "http://localhost:8090" + uri;

        String response;
        try {
            response = HttpConnectionUtils.connection(url, HttpConnectionUtils.POST, list);
        } catch (Exception e) {
            LogService.error(LOGGER_NAME + ": HTTP调用错误", e);
            responseMap.put("status", 0);
            responseMap.put("msg", e.getMessage());
            responseMap.put("data", null);
            return SUCCESS;
        }

        responseMap.put("status", 1);
        responseMap.put("msg", "SUCCESS");
        responseMap.put("data", response);
        return SUCCESS;
    }

    @Override
    @JSON(serialize = false)
    public String getActionId() {
        return this.getClass().getName();
    }

    @Override
    @JSON(serialize = false)
    public ArrayList<ControlLogCategory> getProduct() {
        return null;
    }

    @Override
    @JSON(serialize = false)
    public UserVO getUserVO() {
        return null;
    }

    private SimpleDateFormat getSimpleDateFormat() {
        if (sdf.get() == null) {
            sdf.set(new SimpleDateFormat(DEFAULT_DATE_FORMAT));
        }
        return sdf.get();
    }

    private void setResponseJson(int status, String msg) {
        if (responseMap == null) {
            responseMap = new HashMap<>(2, 1);
        }
        msg = msg == null ? "success" : msg;
        responseMap.put("status", status);
        responseMap.put("msg", msg);
    }

    /**
     * 上传图片到七牛
     * @param file
     * @return 图片地址
     * @throws Exception
     */
    private String uploadPictureToQiniu(File file) throws Exception{
    	String url = null;
    	if(file != null){
    		FileInputStream in = new FileInputStream(file);
			url = QiniuUploadUtils.updateImg("loan_weixin_img", in, null, new Configuration(Zone.zone0()));
    	}
    	return url;
    }
    
    
    /**
     * 获取上传图片的路径
     * @return 图片url
     */
    private String getPicturePath(){
    	File file = null;
    	String dstPath = null;
		if (imageFileFileName != null) {
             dstPath = ServletActionContext.getServletContext().getRealPath(savePath);
             file = new File(dstPath);
             if (!file.exists()) {
            	 file.mkdirs();
             }
             dstPath = dstPath +  File.separator + imageFileFileName;
             file = new File(dstPath);
             try {
					FileCopyUtils.copy(imageFile, file);
				} catch (IOException e) {
					LogService.error(e);
			}
         }
    	return dstPath;
    }


    /**
     * 上传永久图片素材到微信服务器
     * @param productId 微信公众号产品ID
     * @param picUrl 图片链接
     * @return
     */
   private String uploadPermanentImage(String productId, String picUrl){

       String url = ApplicationProperties.get("upload-permanent-image-url");
       UploadPermanentImageRequest uploadPermanentImageRequest = new UploadPermanentImageRequest();

       uploadPermanentImageRequest.setProductId(productId);
       uploadPermanentImageRequest.setImageUrl(picUrl);
       String responseJson = HttpConnectionUtils.connection(url, HttpConnectionUtils.POST, new Gson().toJson(uploadPermanentImageRequest));
       LogService.info("图片：" + picUrl + " 请求上传素材接口响应参数：" + responseJson);
       Result result = new Gson().fromJson(responseJson, Result.class);
       String mediaId = "";
       if(ResultUtils.isSuccess(result)){
           mediaId = (String) result.getData();
       }
       return mediaId;

   }

    public Set<String> getAllChannels() {
        return allChannels;
    }

    public Set<String> getCodeChannels() {
		return codeChannels;
	}
    
    public Map<String, Object> getResponseMap() {
        return responseMap;
    }

    public QueryListUtil.DataTableResponseInfo getResponseInfo() {
        return responseInfo;
    }

    public Set<String> getActivityNameList() {
        return activityNameList;
    }

    public WeixinActivityAction setActivityNameList(Set<String> activityNameList) {
        this.activityNameList = activityNameList;
        return this;
    }

    @Override
    public Object getModel() {
        return new Object();
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public String getFileName() {
        return fileName;
    }

    public WeixinActivityAction setParams(Map<String, Object> params) {
        this.params = params;
        return this;
    }

    public WeixinActivityAction setUpload(File upload) {
        this.upload = upload;
        return this;
    }
    
    public WeixinActivityAction setUploadContentType(String uploadContentType) {
        this.uploadContentType = uploadContentType;
        return this;
    }

    public WeixinActivityAction setImageFile(File imageFile) {
        this.imageFile = imageFile;
        return this;
    }
    
    public WeixinActivityAction setImageFileFileName(String imageFileFileName) {
        this.imageFileFileName = imageFileFileName;
        return this;
    }

    public WeixinActivityAction setSavePath(String savePath) {
        this.savePath = savePath;
        return this;
    }


    public List<String> getKeywordList() {
        return keywordList;
    }

    public static class Keyword {
        private String name;

        public Keyword() {
        }

        public String getName() {
            return name;
        }

        public Keyword setName(String name) {
            this.name = name;
            return this;
        }
    }

    public Map<String, Object> getParams() {
        return params;
    }

    private void updateWeixinKeywordCache(Integer weixinType) {
        if (weixinType != null) {
            String textFlagKey =  WeixinRedisKey.TEXT_MESSAGE_HANDLE+ weixinType;
            String eventFlagKey = WeixinRedisKey.EVENT_MESSAGE_HANDLE + weixinType;
            		
            String newFlag = String.valueOf(System.currentTimeMillis());

            JedisUtils.set(textFlagKey, newFlag);
            JedisUtils.set(eventFlagKey, newFlag);
        }
    }
}
